'use strict';

const Service = require('egg').Service;
const uuidv4 = require('uuid').v4;
// const readline = require('linebyline')
const fs = require('fs');
const iconv = require('iconv-lite');

class BookService extends Service {

  // 返回首页数据
  async getHomeData() {
    const res = {};
    // 获取书籍分类
    const classifyList = await this.app.mysql.select('classify');
    // 查询已上架，已完结的数据
    const bookResult = await this.app.mysql.query('select id,name,cover,classifyId,cv,pv from book a  where(select count(1) from book b where b.classifyId = a.classifyId and b.cv >= a.cv) <=6 and status=1 and isShow=1 order by a.classifyId, a.pv desc');
    // console.log('categoryList:',categoryList);
    // console.log('bookResult:', bookResult);
    if (classifyList && bookResult) {
      // 将cover地址转成带域名地址
      bookResult.forEach(item => {
        item.cover = this.config.baseUrl + item.cover;
      });
      // 将分类由数组形式转化成对象形式
      const classifyObj = {};
      classifyList.forEach(item => {
        classifyObj[item.id] = item;
      });
      // 将数组转化成自己想要的对象形式
      const bookObj = {};
      bookResult.forEach(item => {
        // 有些分类处于某些原因会隐藏，默认值展示能展示的分类。
        if (classifyObj[item.classifyId].isShow) {
          bookObj[item.classifyId] = bookObj[item.classifyId] || [];
          bookObj[item.classifyId].push(item);
        }
      });
      const booklist = [];
      // console.log('bookResult:',bookResult);
      // console.log('categoryObj:',categoryObj);
      for (const key of Object.keys(bookObj)) {
        // console.log('categoryObj[key]:',categoryObj[key]);
        booklist.push({
          classifyId: key,
          classifyName: classifyObj[key].name,
          books: bookObj[key],
        });
      }

      // 把不能显示的分类过滤掉
      const filtedClassifyList = classifyList.filter(item => {
        return item.isShow;
      });
      res.code = 0;
      res.data = {
        classifyList: filtedClassifyList,
        booklist,
      };
    } else {
      res.code = -1;
      res.msg = '获取首页数据失败';
    }
    return res;
  }

  async addBook(data) {
    const res = {};
    // 先判断书籍是否存在
    const book = await this.getBookByName({
      name: data.name,
    });
    if (book.code === 0) {
      res.code = -1;
      res.msg = '书籍已存在';
      res.data = book.data;
    } else {
      const uId = uuidv4();
      data.id = uId;
      await this.app.mysql.insert('book', data);
      const book = await this.getBookByName({
        name: data.name,
      });
      res.code = 0;
      res.msg = '书籍加入成功';
      res.data = book.data;
    }
    return res;
  }
  // 精确查询：书籍名称是唯一的，根据书籍名称查询书籍信息
  async getBookByName(query) {
    const res = {};
    // 默认值显示show为1的图书
    const book = await this.app.mysql.get('book', {
      ...query,
    });

    if (book) {
      res.code = 0;
      res.msg = '书籍已存在';
      res.data = book;
    } else {
      res.code = -1;
      res.msg = '书籍不存在';
    }
    return res;
  }
  async getAllBook(query) {

    // 每一页的数量
    // let pageSize = query.pageSize
    // 当前页
    // let curPage = ctx.query.curPage
    const pageQuery = {};
    if (query.limit) {
      pageQuery.limit = +query.limit;
    }
    if (query.offset) {
      pageQuery.offset = +query.offset;
    }
    const res = {};
    // 获取书籍总数量
    // const bookNums = await this.app.mysql.query('select count(*) from book')
    const book = await this.app.mysql.select('book', {
      where: {},
      ...pageQuery,
      orders: [[ 'createTime', 'desc' ]],
    });

    const bookTotalResult = await this.app.mysql.query('select count(id) as total from book');

    // console.log('bookTotalResult:', bookTotalResult);
    // 获取书籍分类
    const classifyList = await this.app.mysql.select('classify');

    // 将分类由数组形式转化成对象形式
    const classifyObj = {};
    classifyList.forEach(item => {
      classifyObj[item.id] = item;
    });


    // const pageData = {
    //   total:bookNums,
    //   curPage:query.curPage
    // }
    if (book && classifyList) {
      book.forEach(item => {
        item.cover = this.config.baseUrl + item.cover;
        item.classifyName = classifyObj[item.classifyId].name;
      });

      res.code = 0;
      res.msg = '获取书籍成功';
      res.data = {
        total: bookTotalResult[0].total,
        list: book,
      };
      // res.pageData = pageData
    } else {
      res.code = -1;
      res.msg = '书籍不存在';
    }
    return res;
  }
  // 删除书籍
  async deleteBookById(data) {
    const res = {};
    const result = await this.app.mysql.update('book', {
      show: 0,
    }, {
      where: {
        id: data.id,
      },
    });
    if (result.affectedRows === 1) {
      res.code = 0;
      res.msg = '书籍删除成功';
    } else {
      res.code = -1;
      res.msg = '书籍删除失败';
    }
    return res;
  }
  // 更新书籍
  async updateBookById(id, data) {
    const res = {};
    const result = await this.app.mysql.update('book', data, {
      where: {
        id,
      },
    });
    if (result.affectedRows === 1) {
      res.code = 0;
      res.msg = '书籍更新成功';
    } else {
      res.code = -1;
      res.msg = '书籍更新失败';
    }
    return res;
  }

  // 根据分类获取书籍
  async getBookByClassify(classifyId, pageSize, curPage, restQuery) {
    const res = {};

    const selectQuery = {
      where: {
        classifyId,
        // ...restQuery
      },
      orders: [[ 'pv', 'desc' ]],
    };
    if (pageSize !== undefined && curPage !== undefined) {
      pageSize = Number(pageSize);
      curPage = Number(curPage);
      selectQuery.limit = pageSize;
      selectQuery.offset = pageSize * (curPage - 1);
    }
    // console.log('restQuery:',restQuery);
    if (restQuery.isShow !== undefined) {
      selectQuery.where.isShow = restQuery.isShow;
    }
    if (restQuery.status !== undefined) {
      selectQuery.where.status = restQuery.status;
    }
    // console.log('selectQuery:',selectQuery);
    // console.log('pageSize:',pageSize);
    // console.log('curPage:',curPage);
    // console.log('selectQuery:',selectQuery);
    const result = await this.app.mysql.select('book', selectQuery);

    const countResult = await this.app.mysql.query('select count(id) as total from book where classifyId=' + classifyId);
    if (result) {
      // 修改书籍的分类和下载地址
      result.forEach(item => {
        item.cover = this.config.baseUrl + item.cover;
      });
      res.code = 0;
      const resData = {
        total: countResult[0].total,
        books: result,
      };
      if (pageSize !== undefined && curPage !== undefined) {
        resData.pageSize = pageSize;
        resData.curPage = curPage;
      }
      res.data = resData;
      res.msg = '获取书籍成功';
    } else {
      res.code = -1;
      res.msg = '获取书籍失败';
    }
    return res;
  }
  // 根据id获取书籍信息
  async getBookById(id) {
    const res = {};
    const result = await this.app.mysql.get('book', {
      id,
    });
    if (result) {
      result.cover = this.config.baseUrl + result.cover;
      res.code = 0;
      res.data = result;
    } else {
      res.code = -1;
      res.msg = '获取书籍失败';
    }
    return res;
  }

  // 模糊查询  根据名字获取书籍信息
  async getBooksByName(query) {
    console.log('getBooksByName query:', query);
    const res = {};
    const bookName = query.bookName;
    const isShow = query.isShow;
    const status = query.status;
    let andWhereStr = '';
    if (isShow) {
      andWhereStr += ' and isShow=' + Number(isShow);
    }
    if (status) {
      andWhereStr += ' and status=' + Number(status);
    }
    const whereStr = `select id,name,cover,brief from book where name like "%${bookName}%" ${andWhereStr}`;
    console.log('whereStr:', whereStr);
    const result = await this.app.mysql.query(whereStr);
    if (result) {
      result.forEach(item => {
        item.cover = this.config.baseUrl + item.cover;
      });
      res.code = 0;
      res.data = result;
    } else {
      res.code = -1;
      res.msg = '获取书籍失败';
    }
    return res;
  }
  // 统计书籍被点击的数量
  async addBookCvById(id) {
    const res = {};
    // let cResult = await this.app.mysql.query(`update book set cv=cv+1 where id= ${id}`)
    // console.log('cResult:',cResult);
    const preResult = await this.app.mysql.get('book', { id });
    if (preResult) {
      const cv = preResult.cv;
      const result = await this.app.mysql.update('book', { id, cv: cv + 1 });
      if (result) {
        res.code = 0;
        res.msg = '点击量加1';
      } else {
        res.code = -1;
        res.msg = '点击量统计失败';
      }
    } else {
      res.code = -1;
      res.msg = '点击量统计失败';
    }

    return res;
  }
  // 统计书籍浏览量
  async addBookPvById(id) {
    const res = {};
    // let cResult = await this.app.mysql.query(`update book set cv=cv+1 where id= ${id}`)
    // console.log('cResult:',cResult);
    const preResult = await this.app.mysql.get('book', { id });
    if (preResult) {
      const pv = preResult.pv;
      const result = await this.app.mysql.update('book', { id, pv: pv + 1 });
      if (result) {
        res.code = 0;
        res.msg = '浏览量加1';
      } else {
        res.code = -1;
        res.msg = '浏览量统计失败';
      }
    } else {
      res.code = -1;
      res.msg = '浏览量统计失败';
    }

    return res;
  }
  async updateBookPathAndStatus(bid, bookPath, status) {
    const serverBookPath = bookPath.slice(3).replace(/\\/g, '/');
    const result = await this.app.mysql.update('book', { id: bid, path: serverBookPath, status });
    // console.log('updateBookPath result:',result);
    if (result.affectedRows === 1) {
      return {
        code: 0,
      };
    }
    return {
      code: -1,
    };

  }
  // 上传书籍
  async splitBook2Category(bid, bookPath, delimiter, chaptersNum) {
    const book = await this.app.mysql.get('book', { id: bid });
    const res = {};
    if (book) {
      let data = fs.readFileSync(bookPath);
      // utf-8编码头两个字节为ef bb。unicode编码头两个字节为ff fe或者fe ff
      if ((data[0] === 0xef && data[1] === 0xbb) || (data[0] === 0xfe && data[1] === 0xff) || (data[0] === 0xff && data[1] === 0xfe)) {
        if (data[0] === 0xEF && data[1] === 0xBB && data[2] === 0xBF) {
          console.log('带bom头的utf-8');
          data = data.slice(3);
        } else {
          console.log('utf-8编码');
        }
        data = iconv.decode(data, 'utf-8');
      } else {
        console.log('gbk编码');
        // console.log('before decode data:', data.slice(0, 50));
        // ansi编码 gbk是ansi编码的子集
        data = iconv.decode(data, 'gbk');
      }

      // return
      const lines = data.split(/\r?\n/);
      // console.log('lines.length:', lines.length);
      // console.log('lines data:', lines.slice(1510, 1520));
      // let temp = lines.slice(1514,1515)[0]
      // console.log('lines data:',temp);
      // console.log('delimiter:',delimiter);
      const delimiterReg = new RegExp(delimiter);
      // console.log('delimiterReg:', delimiterReg);
      // console.log('delimiterReg.test(temp):',delimiterReg.test(temp));
      // 段落
      /**
       * category = [{bid:'', title:'',content:''}]
       */
      const categoryList = [];
      let title = '';
      let content = '';
      for (const line of lines) {
        if (delimiterReg.test(line)) {
          if (content) {
            // 当进入if，且content有数据，说明一个段落已经遍历完成
            if (title) {
              // 只有存在title才能存储，避免录入书籍前言开头的乱七八糟的东西
              categoryList.push({
                id: uuidv4(),
                title,
                seq: categoryList.length + 1,
                content,
                bid,
                bName: book.name,
              });
            } else {
              content = '';
            }

          }
          // 恢复初始值
          title = line.trim();
          content = '';
        } else {
          content += line + '\r\n';
        }
      }
      // 最后一章因为不再走for里if，所以会漏掉，在这里补上
      categoryList.push({
        id: uuidv4(),
        title,
        seq: categoryList.length + 1,
        content,
        bid,
        bName: book.name,
      });

      console.log('categoryList.length', categoryList.length);
      if (chaptersNum && +chaptersNum !== categoryList.length) {
        res.code = -1;
        res.msg = `实际章节数理论章节数不一致，可能是文件编码格式不对引起的。实际章节数${categoryList.length},章节分别为${categoryList.map(category => category.title).join(',')}`;
        return res;
      }
      // return
      if (categoryList.length) {
        const cResult = await this.ctx.service.category.addAllCategoryByOneTime(categoryList);
        // console.log('cResult:',cResult);
        if (cResult.code === 0) {
          // 将文件路径更新到数据库中
          try {
            const uPathResult = await this.updateBookPathAndStatus(bid, bookPath, 1);
            // console.log('uPathResult:',uPathResult);
            if (uPathResult.code === 0) {
              res.code = 0;
              res.msg = '批量添加章节成功';
            } else {
              res.code = -1;
              res.msg = '更新书籍路径失败';
            }

          } catch (error) {
            res.code = -1;
            res.msg = '更新书籍路径失败';
          }


        } else {
          res.code = -1;
          res.msg = '批量添加章节失败';
        }
      } else {
        res.code = -1;
        res.msg = '章节匹配符没有匹配任何章节';
      }

    } else {
      res.code = -1;
      res.msg = '书籍id不存在';
    }


    return res;
  }

}

module.exports = BookService;
